暑假前因为种种原因没有把百度IFE的先期课程学完,这个暑假又参加了相关项目开发,边做边学也总结了一些教训。现在打算写一个系列的文章,把这种集中学习中遇到一些令我的困扰一时的点好好再总结一番。而这些因应工程实践而生的点本身又多是琐碎的技术细节,若读者正好有相应的疑惑,也希望能给你解决问题提供一定帮助。
inline-block元素间自动产生间隙问题
这是一个比较经典的问题了,横向的间隙与HTML代码中inline-block元素和别的元素间有空格有关,而纵向的则是由于垂直方向上inline-block下缘默认与自动生成的匿名框的baseline对齐后,baseline下面剩下的行高(baseline类似我们书写英文的四线本子上那倒数第二根线,更多解释可见张鑫旭这篇文章或者他新出的css课程)。这些自动产生的空隙一般不是我们做布局时想要的,比如下面这个demo中定高容器里的黄块硬是被图片给挤下去了。而解决方法便是消除img元素产生的空隙:
因为只是在容器里上下布局,对于图片可直接让其
display: block;
,还可以抓住源头,让图片的
vertical-align: 非baseline;
或者在container上设置
line-height: 0;
,行高没有了空隙也就没啦与第3种同理,在container上设置
font-size: 0;
,在有需要添加文字的地方再设置字号即可
上面例子是针对纵向的空隙;至于横向的方法就更多了。
具有button特点的元素和其他元素计算宽高的不同
这个问题在搜索框和搜索按钮这一组合上经常遇见(demo见下面)。不过搜索按钮常为type="submit"
的input元素,但其也特性类似于button元素,那就是它们的width/height=内容的width/height;而其他元素则是width/height=内容的width/height+padding+border。不同的原因在于前者默认box-sizing: border-box;
,而后者默认为box-sizing: content-box;
。
所以解决方法就是将两者的box-sizing统一,要么将搜索框设置box-sizing: border-box;
,要么将搜索按钮设置box-sizing: content-box;
。而至于它们中间那个有点碍眼的空隙,我相信读者们也应该会自己去掉了吧?
同处一行的block和inline-block元素对齐问题
这个问题的demo见下,其中几个内容不相同(有文字、有block)的inline-block元素实现并列时,出现了垂直方向上对不齐的问题。后来我对wrapper使用vertical-align:middle;
解决了该问题。
解决之后,这个问题背后的原理却至今是个让我头疼的东西。因为里面涉及line-height
和vertical-align
两个属性的种种纠结。我们知道,inline或inline-block元素在垂直方向上默认以其baseline与父元素的baseline对齐。于是我想了如下一个解释:
wrapper与container的baseline对齐后,wrapper内部的文字也与wrapper保持baseline对齐,此时文字再加上
line-height
撑开无名行内框会导致wrapper也被撑起,进而偏离原来对齐方式。而文字的line-height
对container的baseline也会造成偏移,并以此进一步影响container中其他wrapper。-demo-所以结论就是,我遇到的对不齐的情况是文字依靠
line-height
控制了其wrapper以及container的baseline位置。若将wrapper全部修改为vertical-align:middle;
则破解了其控制。-demo-
貌似还能解释得通,然而继续深究下去,比如我只把第一个wrapper设置vertical-align:middle;
,-demo- 则wrapper相比默认情况出现了下移,这可以解释为第一个wrapper与container中间对齐时即相比baseline对齐有所下移,文字再次按撑开行高。
但wrapper与container中间对齐时应该相比baseline对齐上移才对(比如上个demo中间两个wrapper),为何还会出现下移呢?
更进一步,若是光把wrapper里的文字设置vertical-align:middle;
则不仅仅文字出现了下移,还在未修改line-height
时改变了wrapper高度。-demo- 这又是为何?
当然这毕竟不是什么影响开发的大问题,而且这种抠细节、深究css原理的的问题也不是那么容易讲清楚的,所以至今我找了许多资料也未能让我明了。但如果各位读者有这方面的解决思路,非常欢迎与我交流~
2016.5.27更新:
回过头来重新研究了下,看了一些新资料后发现之前的结论其实不太对,解决这个对齐问题的关键就是vertical-align
的定位机制而已,和line-height
本身没有多大关系。
但在开始讨论之前,必须得先理清vertical-align
的作用对象,该属性只是对设置了它的内联元素起作用而已,对其子元素是没有影响的。千万别因为它和垂直定位有关,就把它的作用和text-align
混淆,我就是因为这么疏忽大意浪费了不少时间。
关于基线对齐
好了,接下来就可以来讨论vertical-align
的定位机制了,由于该属性默认值为baseline
,这也是我们最常遇到的情况,其定位效果就是让内联元素的基线和同一行的元素的基线相对齐。但要注意同一行内每个元素的基线未必是相同的,具体解释可参考这篇文章,这里只提一下结论:
内联元素基线的确定:
一个inline-block元素,如果里面没有inline内联元素,或者overflow不是visible,则该元素的基线就是其margin底边缘;否则,其基线就是元素里面最后一行内联元素的基线。
因为基线的不同,这就会导致内联元素在默认使用vertical-align:baseline
定位时,会出现同一行元素的错位问题。这样,上面的第一个demo就能解释了,中间那个元素没有内联子元素,其基线为margin底边缘;而左右两侧的两个由于内含文字,基线为文本底端,由于三者的基线要对齐,结果自然就会有错位。第二个demo同样也是基线定位导致的问题,只是行高变大了点导致文本溢出、基线也溢出来罢。
关于中线对齐
接下来研究下为何设置vertical-align:middle
就能使错位情况消失(也就是第三个demo的情况)。
通过上面对基线对齐的讨论,你可能会认为中线对齐就是指定元素中线和同一行元素的中线对齐而已。但很遗憾,这样并不太对,某个元素的中线可以说横穿正中间,而与它同一行元素却可能有不同的大小,甚至被已经被设置了不同的对齐方式、有不同的“所谓中线”,这样就不能笼统地得出“同一行元素的中线”的概念。上面让我头疼的demo4和demo5就是这种情况,因为它们在同一行中混杂了中线对齐和基线对齐,所以中线的确定并不是像我原来想的那么简单。
那么有没有和基线一样的确定准则呢?当然有,一个业界公认的标准就是同一行内联元素中,中线穿过的是小写x
的中点。也就是说,所谓中线对齐就是横穿指定元素正中间那条线,与同一行元素的小写x
中点相对齐。
所以设置vertical-align:middle
能使错位情况消失并没有什么神奇的,只是三个内联元素的中线一致对齐了而已。至于demo4和demo5,各位可在各个wrapper
外加上几个x
看看中线对齐是不是真的这样,只要理解了对齐方式,这两个demo的错位现象也就很好解释了。
其他对齐方式
其实通过上面的讨论,可以知道要理清vertical-align
的定位机制,只要抓住指定元素的哪根线和父元素的哪根线相对齐即可。至于他的对齐方式也不外乎就是对齐的线不同而已,具体可参见MDN吧,上面写得够详细了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。